package com.ganbo.ms.websocket.config;

import com.ganbo.ms.websocket.utils.FastJsonUtil;
import com.ganbo.ms.websocket.vo.WebSocketMsgVO;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@ServerEndpoint("/webSocket/{id}")
public class WebSocketServer {

    // 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    // concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    // 建立连接成功调用
    @OnOpen
    public void onOpen(final Session session, @PathParam(value = "id") final String id) {
        session.setMaxIdleTimeout(10 * 60 * 1000);
        try {
            synchronized (WebSocketServer.sessionPools) {
                if (WebSocketServer.sessionPools.containsKey(id)) {
                    WebSocketServer.sessionPools.remove(id);
                } else {
                    WebSocketServer.addOnlineCount();
                }
                WebSocketServer.sessionPools.put(id, session);
            }
            System.out.println(id + "加入webSocket！当前人数为" + WebSocketServer.onlineNum);
            final WebSocketMsgVO messageVO = new WebSocketMsgVO();
            messageVO.setToId(id);
            messageVO.setContent("欢迎" + id + "加入连接！");
            messageVO.setSendMsgType("open");
            sendMessage(session, FastJsonUtil.objectTOJsonString(messageVO));
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }

    // 关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "id") final String id) {
        synchronized (WebSocketServer.sessionPools) {
            if (WebSocketServer.sessionPools.containsKey(id)) {
                WebSocketServer.sessionPools.remove(id);
                WebSocketServer.subOnlineCount();
            }
        }
        System.out.println(id + "断开webSocket连接！当前人数为" + WebSocketServer.onlineNum);
    }

    // 收到客户端信息
    @OnMessage
    public void onMessage(final String message) throws IOException {
        System.out.println("收到客户端消息：" + message);
        try {
            if (!WebSocketServer.sessionPools.isEmpty()) {
                final WebSocketMsgVO messageVO = FastJsonUtil.jsonStringToObject(message, WebSocketMsgVO.class);
                if (WebSocketServer.sessionPools.containsKey(messageVO.getToId())) {
                    sendMessage(WebSocketServer.sessionPools.get(messageVO.getToId()), message);
                }
            }
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    // 错误时调用
    @OnError
    public void onError(final Session session, final Throwable throwable) {
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    // 发送消息
    private void sendMessage(final Session session, final String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                System.out.println("发送数据：" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }

    public static void addOnlineCount() {
        WebSocketServer.onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        WebSocketServer.onlineNum.decrementAndGet();
    }
}
